// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-object.keys
description: >
  Proxy [[OwnPropertyKeys]] trap does not skip non-enumerable keys when validating invariant:
  * If the target object is not extensible, then the result List must contain all the keys of
    the own properties of the target object and no other values.
info: |
  Object.keys ( O )

  ...
  2. Let nameList be ? EnumerableOwnPropertyNames(obj, "key").

  EnumerableOwnPropertyNames ( O, kind )

  ...
  2. Let ownKeys be ? O.[[OwnPropertyKeys]]().

  [[OwnPropertyKeys]] ( )

  ...
  11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
  16. For each element key of targetKeys, do
    a. Let desc be ? target.[[GetOwnProperty]](key).
      ...
    c. Else,
  ...
  18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
  ...
    a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
features: [Proxy]
---*/

function Test() {
    var target = {};
    Object.defineProperty(target, 'prop', {
      value: 2,
      writable: true,
      enumerable: false,
      configurable: true,
    });

    var proxy = new Proxy(target, {
      ownKeys: function() {
        return [];
      },
    });

    Object.preventExtensions(target);

    assert.throws(TypeError, function() {
      Object.keys(proxy);
    });
}

// preheat
const NUMBER_OF_PREHEAT = 1;
for (let i = 0; i < NUMBER_OF_PREHEAT; i++) {
    Test();
}

ArkTools.jitCompileAsync(Test);
assert.sameValue(ArkTools.waitJitCompileFinish(Test), true, '[JIT] JIT disabled.');

// test
const NUMBER_OF_TEST = 1; // or 2
for (let i = 0; i < NUMBER_OF_TEST; i++) {
    Test();
}
